#include "LightState.h"


RenderState::Type LightState::get_type() const
{
	return GL_LIGHT;
}

LightState::~LightState()
{
	detach_all();
}

LightState::LightState()
{
}


void LightState::update( RenderState*& old_state )
{
	assert( old_state == );
	if ( old_state != m_default )
		return;

	for ( unsigned int i = 0; i < MAX_LIGHTS; i++ )
	{
		if ( m_light[index] )
		{
			unsigned int pos = m_default->attach( m_light[index] );
			assert( pos < MAX_LIGHTS );
		}
	}
}

void LightState::restore( RenderState* old_state )
{
	assert( old_state == m_default );
	if ( old_state != m_default )
		return;

	for ( unsigned int i = 0; i < MAX_LIGHTS; i++ )
	{
		if ( m_light[i] )
		{
			// A check is made here to make sure no one else has removed the light.
			unsigned int pos = m_default->detach( m_light[i] );
			assert( pos < MAX_LIGHTS );
		}
	}
}

RenderState* LightState::copy()
{
	LightState* state = new LightState;
	for ( unsigned int i = 0; i < MAX_LIGHTS; i++ )
		state->m_light[i] = m_light[i];
	
	return state;
}

unsigned int LightState::attach( Light* light )
{
	assert( light );
	if ( !light )
		return MAX_LIGHTS;

	unsigned int index;
	// a light should not be attached twice
	for ( index = 0; index < MAX_LIGHTS; index++ )
	{
		if ( m_light[index] 
		&& m_light[index]->get_id() == light->get_id())
		{
			assert( false );
			return MAX_LIGHTS;
		}
	}

	for ( index = 0; index < MAX_LIGHTS; index++ )
	{
		if ( m_light[index] == 0 )
		{
			m_light[index] = light;
			return index;
		}
	}

	return MAX_LIGTHS;
}

unsigned int LightState::detach( Light* light )
{
	assert( light );
	if ( !light )
		return MAX_LIGHTS;

	for ( unsigned int index = 0; index < MAX_LIGHTS; index++ )
	{
		if ( m_light[index] 
		&& m_light[index]->get_id() == light->get_id() )
		{
			m_light[index] = 0;
			return index;
		}
	}

	return MAX_LIGHTS;
}

LightPtr LightState::detach( unsigned int index )
{
	assert( index < MAX_LIGHTS );
	if ( index >= MAX_LIGHTS )
		return 0;
	LightPtr save = m_light[index];
	m_light[index] = 0;
	return save;
}

void LightState::detach_all()
{
	for ( unsigned int index = 0; index < MAX_LIGHTS; index++ )
		m_light[index] = 0;
}

unsigned int LightState::get_lights() const
{
	unsigned int num = 0;
	for ( unsigned int i = 0; i < MAX_LIGHTS; i++ )
	{
		if ( m_light[i] )
			num++;
	}
	return num;
}

Light* LightState::get( unsigned int i )
{
	assert( i < MAX_LIGHTS );
	if ( i >= MAX_LIGHTS )
		return 0;

	return m_light[i];
}
